/*
 * RenderWindow.h
 *
 *  Created on: 2009/01/05
 *      Author: Yongshik Cho
 */

#ifndef RENDERWINDOW_H_
#define RENDERWINDOW_H_

#ifndef PREREQUISITES_H_
#	include "core/Prerequisites.h"
#endif

#ifndef ISINGLETON_H_
#	include "core/ISingleton.h"
#endif

#ifndef RECT2D_H_
#	include "core/Rect2D.h"
#endif


struct DeviceCaps
{
	int32 horzsize;
	int32 vertsize;
	int32 horzres;
	int32 vertres;
	int32 logpixelsx;
	int32 logpixelsy;
	int32 bitspixel;
	int32 planes;
	int32 physicalwidth;
	int32 physicalheight;
	int32 physicaloffsetx;
	int32 physicaloffsety;
	int32 vrefresh;
};

class RenderWindow : public ISingleton<RenderWindow>
{
private:
	static const String _RenderWindowClassName;
	static const String _DEFAULT_WINDOW_NAME;

	static const int32 _DEFAULT_POS_X = 0;
	static const int32 _DEFAULT_POS_Y = 0;
	static const int32 _DEFAULT_WIDTH = 800;
	static const int32 _DEFAULT_HEIGHT = 600;

public:
	enum WindowSizeType
	{
		_SIZE_RESTORED = 0,
		_SIZE_MINIMIZED,
		_SIZE_MAXIMIZED,
		_SIZE_MAXSHOW,
		_SIZE_MAXHIDE
	};

public:
	RenderWindow(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int32 nCmdShow,
			HWND hwnd = 0, String title = _DEFAULT_WINDOW_NAME, int8 centerType = Rect2D::CENTER_NONE,
			int32 x = _DEFAULT_POS_X, int32 y = _DEFAULT_POS_Y, int32 width = _DEFAULT_WIDTH, int32 height = _DEFAULT_HEIGHT,
			bool fullscreen = false, bool resizable = false);

	virtual ~RenderWindow();

	inline const HWND& getWnd() const { return mWnd; }
	const HDC& getDC() const { return mDeviceContext; }

	inline const int32 getPosX() const { return mPosX; }
	inline const int32 getPosY() const { return mPosY; }
	inline void setPosX(const int32 x) { mPosX = x; }
	inline void setPosY(const int32 y) { mPosY = y; }
	virtual void setPosition(const int32 x, const int32 y);
	inline const int32 getWidth() const { return mWidth; }
	inline void setWidth(const int32 w) { mWidth = w; }
	inline const int32 getHeight() const { return mHeight; }
	inline void setHeight(const int32 h) { mHeight = h; }
	virtual void setSize(const int32 sx, const int32 sy);
	virtual void setZorder(const HWND& hWndInsertAfter);
	inline const uint8 getCenterType() const { return mCenterType; }
	const Rect2D getClientRect();

	virtual void run();

	virtual const HWND getDesktopWnd() const { return mDesktopWnd; }
	virtual const DeviceCaps& getDesktopCaps() const { return mDesktopCaps; }
	virtual const DeviceCaps& getCaps() const { return mCaps; }

public:
	static RenderWindow& GetInstance()
	{
		assert(m_pInstance);
		return *m_pInstance;
	}
	static RenderWindow* GetInstancePtr()
	{
		return m_pInstance;
	}

private:
	virtual void create();
	virtual void retrieve();

	static LRESULT WINAPI WindowMessageProcedure(HWND hWnd, uint32 msg, WPARAM wParam, LPARAM lParam);

	virtual void checkDesktop();
	virtual const DeviceCaps getDeviceCaps(const HDC& hdc);
	void makeWindowPosition(int32& x, int32& y);

private:
	HINSTANCE 	mInstance;
	HINSTANCE 	mPrevInstance;
	String 		mCmdLine;
	int32 		mCmdShow;

	HWND		mWnd;
	DeviceCaps	mCaps;
	HDC			mDeviceContext;
	HWND		mDesktopWnd;
	DeviceCaps	mDesktopCaps;
	bool		mFullscreen;
	bool		mResizable;

	int32		mWidth;
	int32		mHeight;
	int32		mPosX;
	int32		mPosY;

	String		mTitle;
	uint8		mCenterType;
};

#endif /* RENDERWINDOW_H_ */
